package earlystageidea;

/**
 * @author zhoshen
 */
public class EnumDemo
{
    /**
     * @param args
     */
    public static void main( String[] args )
    {

        System.out.println( "Print value in Enum:" );
        for( Fruit f : Fruit.values() )
        {
            System.out.println( EnumUtils.getCode( f ) + ":" + EnumUtils.getDisplayName( f ) );
        }

        System.out.println( "\nGet Enum by code:" );
        Fruit enumByCode = EnumUtils.getEnumByCode( Fruit.values(), 4 );

        System.out.println( enumByCode );

        System.out.println( "\nGet Enum by code(with exception):" );
        Fruit enumByCode1 = EnumUtils.getEnumByCode( Fruit.values(), 8 );

        System.out.println( enumByCode1 );
    }
}

/**
 * @author zhoshen
 */
final class EnumUtils
{
    /**
     * @param e
     */
    public static int getCode( IEnum<?> e )
    {
        return e.getCode();
    }

    /**
     * @param e
     */
    public static String getDisplayName( IEnum<?> e )
    {
        return e.getDisplayName();
    }

    @SuppressWarnings( "unchecked" )
    public static <T extends Enum> T getEnumByCode( final Enum<? extends IEnum>[] values, final int code )
    {
        IEnum<?> found = null;
        for( Enum<? extends IEnum> ie : values )
        {
            if( ( ( IEnum ) ie ).getCode() == code )
            {
                found = ( IEnum ) ie;
                break;
            }
        }
        if( found == null )
        {
            throw new IllegalArgumentException( "Code " + code + " not defined in " + values[0].getClass().getName() );
        }
        else
        {
            return ( T ) found;
        }
    }
}

/*
 * 
 */
enum Fruit implements IEnum
{
    Appl( 1, "Apple" ), Orn( 2, "Orange" ), Pr( 3, "Pear" ), Bnn( 4, "Banana" );
    
    private int code;

    private String text;

    private String displayName;

    Fruit( int code, String displayName )
    {
        this.code = code;
        this.displayName = displayName;
    }
    @Override
    public int getCode()
    {
        return this.code;
    }
    @Override
    public String getDisplayName()
    {
        return this.displayName;
    }
}

interface IEnum<E>
{
    int getCode();

    String getDisplayName();
}